import os
import shutil
import win32api
import win32print
import random
import string
from copy import deepcopy
import re
import time
import datetime
import tkinter as tk
from docx import Document
import requests
from bs4 import BeautifulSoup


class NoInfoError(Exception):
    pass


def print_file(filename):
    win32api.ShellExecute(
        0,
        'print',
        filename,
        '/d:"%s"' % win32print.GetDefaultPrinter(),
        '.',
        0)


def aquire_info(pid):
    patient_result = {}

    get_params = {'id': str(pid)}

    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
    }

    url_get = "http://10.68.1.38:8000/doqleiview/doqleiview.aspx"

    users = requests.Session()

    get_content = users.get(url_get, params=get_params, headers=headers)

    html_doc = get_content.text

    soup = BeautifulSoup(html_doc, 'html.parser')

    json_get = soup.find(
        name="ul",
        attrs={"class": "ztree"}

    )

    if json_get:
        json_get = json_get.attrs

        post_para = {
            'type': json_get['data-type'],
            'mdata': json_get['data-mdata'],
            'integrationim': json_get['data-integrationim'],
            'idata[0].key': 'treeid',
            'idata[0].value': 'tree_1',
            'idata[1].key': 'tid',
            'idata[1].value': 'tree_1_2',
            'mtype': 'HMedical'
        }
        url_menu = "http://10.68.1.39:8888/Menu/ChildMedicalMenu"

        get_json = users.post(
            url_menu,
            headers=headers,
            data=post_para
        )

        menu_respond = get_json.json()

        for i in menu_respond['Data']:
            for j in i['Children']:

                if j['Data']['cname'] == '入院记录':

                    access_id = j['Data']['accessId']

                    pname = j['Data']['pname']
                    cname = j['Data']['cname']
                elif j['Data']['cname'] == '首次病程记录':

                    access_id1 = j['Data']['accessId']

                    pname1 = j['Data']['pname']
                    cname1 = j['Data']['cname']

        post_para_inpatient = {
            'type': json_get['data-type'],
            'mdata': json_get['data-mdata'],
            'integrationim': json_get['data-integrationim'],
            'idata[0].key': 'pname',
            'idata[0].value': pname,
            'idata[1].key': 'cname',
            'idata[1].value': cname,
            'mtype': 'HMedical',
            'idata[2].key': 'accessId',
            'idata[2].value': access_id

        }

        url_result = "http://10.68.1.39:8888/Content/Index"
        result = users.post(
            url_result,
            headers=headers,
            data=post_para_inpatient
        ).text

        soup_result = BeautifulSoup(result, 'html.parser')

        table_list = soup_result.find_all(
            name='table',

        )
        if table_list:

            td_order = table_list[0].find_all('td')

            for i in td_order:
                info_list = i.text.split("：")
                patient_result[info_list[0]] = info_list[1]
            td_dig = table_list[1].find_all('td')
            patient_result["诊断"] = ''.join(td_dig[1].text.split()[1:])
            patient_result["住院号"] = str(pid)

        post_para_inpatient = {
            'type': json_get['data-type'],
            'mdata': json_get['data-mdata'],
            'integrationim': json_get['data-integrationim'],
            'idata[0].key': 'pname',
            'idata[0].value': pname1,
            'idata[1].key': 'cname',
            'idata[1].value': cname1,
            'mtype': 'HMedical',
            'idata[2].key': 'accessId',
            'idata[2].value': access_id1

        }

        result_first = users.post(
            url_result,
            headers=headers,
            data=post_para_inpatient
        ).text

        first_result = BeautifulSoup(result_first, 'html.parser')
        p_f = first_result.find_all('p')[1].text

        content_fit = re.findall(r".+(以.+)一、病例特点.+(查体|体格检查)(.+双肺.+)二、拟诊讨论.+(诊断.+)\(二\).+|2.+", p_f)

        if content_fit:

            patient_result['病史'] = ''.join(content_fit[0]) + "下班密切注意患儿"
        else:
            patient_result['病史'] = p_f + "下班密切注意患儿"

    return patient_result


def to_word(result_json):
    # 将获取的信息存为word文档以便打印 2021年2月01日 19 时 00 分至2021年2月2日08 时 00 分
    cur_date = datetime.datetime.strftime(datetime.datetime.today(), "%Y{}%m{}%d{}").format("年", "月", "日")
    one_day = datetime.timedelta(days=1)
    past_date = datetime.datetime.strftime(datetime.datetime.today() - one_day, "%Y{}%m{}%d{}").format("年", "月", "日")

    cur_hour = int(time.strftime("%M", time.localtime()))
    if cur_hour >= 12:

        time_string = "%s 08时00分至%s 19时00分" % (cur_date, cur_date)
    else:
        time_string = "%s 19时00分至%s 08时00分" % (past_date, cur_date)
    patient_statistic = "原住院人数29 人、入院 %s人、转入 0 人、转出 0 人、出院 0 人、手术 0 人、操作 0人、抢救 0 人、病危（病重） 0 人、死亡 0 人、危急值 0 人、输血 0 人、现住院人数30 人。"

    if os.path.isfile('.\\shift_mod_done.docx'):
        os.remove('.\\shift_mod_done.docx')

    shift_mod = Document("shift.docx")

    t = shift_mod.tables[0]
    t.rows[0].cells[1].text = time_string

    if len(result_json) > 1:
        flag = True
    else:
        flag = False

    for k, v in result_json.items():
        if flag:
            new_row = deepcopy(t.rows[-3])
            t.rows[-2]._tr.addprevious(new_row._element)
        t.rows[-4].cells[0].text = v['床号']
        t.rows[-4].cells[1].text = v['姓名']
        t.rows[-4].cells[2].text = v['性别']
        t.rows[-4].cells[3].text = v['年龄']
        t.rows[-4].cells[4].text = '新入'
        t.rows[-4].cells[5].text = v['入院时间'].split()[1] + v['病史']

    t.rows[1].cells[1].text = patient_statistic % (str(len(result_json)))
    if not os.path.exists('temp'):
        os.mkdir('temp')
    random_file_name = ''.join(random.sample(string.ascii_letters + string.digits, 8))

    shift_mod.save('.\\temp\\%s.docx' % random_file_name)
    os.startfile('.\\temp\\%s.docx' % random_file_name)


def save_to_word(text_info):
    date_to_write = text_info['入院时间'].split()[0]
    d = Document('.\\a_notification.docx')

    # 获取word文档内的表格列表
    t = d.tables
    # 第一个表格为病人基本信息，包括姓名、性别、年龄
    t1 = t[0]

    # 姓名值位于t1.cell(0, 1)，即第一行第2列；
    run = t1.cell(0, 1).paragraphs[0].add_run(text_info['姓名'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 性别值位于t1.cell(0, 3)，即第一行第4列；
    run = t1.cell(0, 4).paragraphs[0].add_run(text_info['性别'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 年龄值位于t1.cell(0, 5)，即第一行第6列；
    run = t1.cell(0, 6).paragraphs[0].add_run(text_info['年龄'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 身份证号
    run = t1.cell(1, 1).paragraphs[0].add_run(text_info['身份证明号'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 住院号
    run = t1.cell(2, 1).paragraphs[0].add_run(text_info['住院号'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 诊断
    run = t1.cell(2, 4).paragraphs[0].add_run(text_info['诊断'])
    run.font.name = '宋体'
    run.font.size = 140000
    # 入院时间
    run = t1.cell(3, 4).paragraphs[0].add_run(date_to_write)
    run.font.name = '宋体'
    run.font.size = 140000
    # 时间1
    run = t1.cell(6, 5).paragraphs[0].add_run(date_to_write)
    run.font.name = '宋体'
    run.font.size = 140000
    # 时间2
    run = t1.cell(8, 3).paragraphs[0].add_run(date_to_write)
    run.font.name = '宋体'
    run.font.size = 140000
    if not os.path.exists('temp'):
        os.mkdir('temp')
    random_file_name1 = ''.join(random.sample(string.ascii_letters + string.digits, 8))

    d.save('.\\temp\\%s.docx' % random_file_name1)
    # 调试
    # os.startfile(os.path.abspath('.\\temp\\%s.docx' % random_file_name1))
    print_file(os.path.abspath('.\\temp\\%s.docx' % random_file_name1))
    random_file_name2 = ''.join(random.sample(string.ascii_letters + string.digits, 8))
    d.save('.\\temp\\%s.docx' % random_file_name2)
    print_file(os.path.abspath('.\\temp\\%s.docx' % random_file_name2))


class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        self.wm_attributes('-topmost', 1)

        sw = self.winfo_screenwidth()
        sh = self.winfo_screenheight()

        ww = 600
        wh = 150
        self.geometry(
            "%dx%d+%d+%d" %
            (ww, wh, (sw - ww) / 2, (sh - wh) / 2))
        self.after(1, lambda: self.focus_force())
        self.iconphoto(False, tk.PhotoImage(file='title.png'))
        self.title('懒才是王道！     -by cbl')
        self.flag = tk.StringVar()
        self.flag.set('交班')
        radio_frame = tk.Frame(self)
        radio_frame.pack()
        tk.Radiobutton(radio_frame, variable=self.flag, text='交班', value='交班').pack(side=tk.LEFT)
        tk.Radiobutton(radio_frame, variable=self.flag, text='医保', value='医保').pack(side=tk.LEFT)

        self.info = tk.StringVar()
        self.info.set('请输入住院号，用空格隔开：')
        self.info_label = tk.Label(self, textvariable=self.info, font=('微软雅黑', 10), )
        self.info_label.pack()
        self.pid = tk.StringVar()
        self.pid.set('21000000 21000001')
        self.pid_e = tk.Entry(self, width=60, textvariable=self.pid, relief='groove',
                              font=('微软雅黑', 10),
                              selectbackground='brown', )
        self.pid_e.bind('<FocusIn>', self.on_select)
        self.pid_e.focus_set()
        self.pid_e.pack()
        btn_frame = tk.Frame(self)
        btn_frame.pack(pady=10)
        btn_ok = tk.Button(btn_frame, text='确 定', width=12, height=1, activebackground='grey',
                           relief='groove')
        btn_ok.bind('<ButtonPress-1>', self.info_)
        btn_ok.bind('<ButtonRelease-1>', self.submit)
        btn_ok.pack(side=tk.LEFT)
        btn_cancel = tk.Button(btn_frame, text='取消', command=self.cancel, width=12, height=1, activebackground='grey',
                               relief='groove')
        btn_cancel.pack(side=tk.RIGHT)

    def info_(self, event):
        self.info_label['fg'] = 'black'
        self.info.set('程序运行中，请稍后...')

    def submit(self, event):
        try:

            result_json = {}
            pid = self.pid.get()
            if pid:
                pid = pid.strip()

                if self.flag.get() == '交班':

                    for i in pid.split():

                        info_back = aquire_info(str(int(i)))
                        if info_back:
                            result_json[i] = info_back
                        else:

                            raise NoInfoError('住院号%s无病历信息，请核对后重试！' % i)

                    if result_json:
                        to_word(result_json)
                elif self.flag.get() == '医保':
                    for yb in pid.split():
                        yb_back = aquire_info(str(int(yb)))
                        if yb_back:
                            save_to_word(yb_back)
                            print_file(os.path.abspath('bcnotification.docx'))
                        else:
                            raise NoInfoError('住院号%s无病历信息，请核对后重试！' % yb)
                self.info_label['fg'] = 'black'
                self.info.set('请输入新病人住院号，用空格隔开：')
                self.pid.set('')
            else:
                self.info_label['fg'] = 'red'
                self.info.set('请输入住院号！')
        except PermissionError:
            self.info_label['fg'] = 'red'
            self.info.set('运行出错：临时文件被占用！\n请关闭程序自动打开的所有word文件后重试！')
            self.pid.set('')
        except ValueError:
            self.info_label['fg'] = 'red'
            self.info.set('请输入有效的住院号后重试！')
            self.pid.set('')
        except NoInfoError as no_info:
            self.info_label['fg'] = 'red'
            self.info.set(no_info)

        except Exception as e:
            self.info_label['fg'] = 'red'
            self.info.set('运行出错：%s。\n请检查后重试！' % e)
            self.pid.set('')

    def on_select(self, event):
        # event.widget 即触发事件的控件，可以直接用它的方法如.select_range()等
        event.widget.select_range(0, tk.END)

    def cancel(self):
        try:
            if os.path.isdir('.\\temp\\'):
                shutil.rmtree('.\\temp\\')
            self.destroy()
        except PermissionError:
            self.info_label['fg'] = 'red'
            self.info.set('无法关闭程序：临时文件被占用！\n请关闭程序自动打开的所有word文件后重试！')


if __name__ == '__main__':
    app = MainWindow()
    app.mainloop()
